package com.tqz.rc.client.naming;

import com.tqz.rc.api.Instance;
import com.tqz.rc.api.ServiceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * <p>负载均衡
 *
 * @author tianqingzhao
 * @since 2021/9/29 10:33
 */
public class Balancer {

    private static final Logger log = LoggerFactory.getLogger(Balancer.class);

    /**
     * report status to server
     */
    public final static List<String> UNCONSISTENT_SERVICE_WITH_ADDRESS_SERVER = new CopyOnWriteArrayList<String>();

    public static class RandomByWeight {

        public static List<Instance> selectAll(ServiceInfo serviceInfo) {
            List<Instance> hosts = serviceInfo.getHosts();

            if (CollectionUtils.isEmpty(hosts)) {
                throw new IllegalStateException("no host to srv for serviceInfo: " + serviceInfo.getServiceName());
            }

            return hosts;
        }

        public static Instance selectHost(ServiceInfo dom) {

            List<Instance> hosts = selectAll(dom);

            if (CollectionUtils.isEmpty(hosts)) {
                throw new IllegalStateException("no host to srv for service: " + dom.getServiceName());
            }

            return getHostByRandomWeight(hosts);
        }
    }

    /**
     * Return one host from the host list by random-weight.
     *
     * @param hosts The list of the host.
     * @return The random-weight result of the host
     */
    protected static Instance getHostByRandomWeight(List<Instance> hosts) {
        log.debug("entry randomWithWeight");
        if (hosts == null || hosts.size() == 0) {
            log.debug("hosts == null || hosts.size() == 0");
            return null;
        }

        Chooser<String, Instance> vipChooser = new Chooser<String, Instance>("www.taobao.com");

        log.debug("new Chooser");

        List<Pair<Instance>> hostsWithWeight = new ArrayList<Pair<Instance>>();
        for (Instance host : hosts) {
            if (host.isHealthy()) {
                hostsWithWeight.add(new Pair<Instance>(host, host.getWeight()));
            }
        }
        log.debug("for (Host host : hosts)");
        vipChooser.refresh(hostsWithWeight);
        log.debug("vipChooser.refresh");
        return vipChooser.randomWithWeight();
    }
}